package top.yueyazhui.storage.service.impl;

import cn.hutool.core.util.ObjectUtil;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.yueyazhui.storage.entity.Storage;
import top.yueyazhui.storage.mapper.StorageMapper;
import top.yueyazhui.storage.service.StorageService;

@Service
@Slf4j
public class StorageServiceImpl implements StorageService {

    @Autowired
    StorageMapper storageMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean prepare(String commodityCode, Integer count) {
        Storage storage = storageMapper.getCountByCommodityCode(commodityCode);
        if (ObjectUtil.isNull(storage)) {
            throw new RuntimeException("商品不存在");
        }
        if (storage.getCount() < count) {
            throw new RuntimeException("商品数量不足，扣库存失败");
        }
        // 冻结商品数量
        storage.setFreezeCount(storage.getFreezeCount() + count);
        storage.setCount(storage.getCount() - count);
        Integer result = storageMapper.updateStorage(storage);
        log.info("{} 商品预扣 {} 件", commodityCode, count);
        return result == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean commit(BusinessActionContext businessActionContext) {
        // 获取 prepare 阶段的两个参数
        String commodityCode = (String) businessActionContext.getActionContext("commodityCode");
        Integer count = (Integer) businessActionContext.getActionContext("count");
        Storage storage = storageMapper.getCountByCommodityCode(commodityCode);
        if (storage.getFreezeCount() < count) {
            throw new RuntimeException("商品数量不足，扣库存失败");
        }
        storage.setFreezeCount(storage.getFreezeCount() - count);
        Integer result = storageMapper.updateStorage(storage);
        log.info("{} 商品扣 {} 件", commodityCode, count);
        return result == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean rollback(BusinessActionContext businessActionContext) {
        // 获取 prepare 阶段的两个参数
        String commodityCode = (String) businessActionContext.getActionContext("commodityCode");
        Integer count = (Integer) businessActionContext.getActionContext("count");
        Storage storage = storageMapper.getCountByCommodityCode(commodityCode);
        if (ObjectUtil.isNull(storage)) {
            log.info("{} 商品不存在", commodityCode);
            return true;
        }
        if (storage.getFreezeCount() >= count) {
            storage.setCount(storage.getCount() + count);
            storage.setFreezeCount(storage.getFreezeCount() - count);
            Integer result = storageMapper.updateStorage(storage);
            log.info("库存释放冻结 {} 商品 {} 件", commodityCode, count);
            return result == 1;
        }
        log.info("库存不需要释放冻结 {} 商品", commodityCode);
        return true;
    }
}
